/****************************************************************************
 *                                                                          *
 * Copyright (c) 2013 Corefaster Elec & Tech Corp.         *
 *	All rights reserved.        				   *
 *                                                                          *
 ****************************************************************************/ 

/****************************************************************************
 * 
 * FILENAME
 *   guard.c
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION
 *     This file is a sample test program used to protect the obdapp not idel 
 *   
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *     None
 *
 * HISTORY
 *     04/27/2014            Ver 1.0 Created by Ray Gu
 *
 * REMARK
 *     None
 **************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>

#include "guard.h"

int newlogIndex = 0;
int checkappstatus = CHECK_ENABLE;
/*
 *检查Log文件夹是否存在
 */ 
void CheckLogDir(void)
{
	if(NULL == opendir(ROOT_LOG))
		mkdir(ROOT_LOG, 0777);		
}

/*
 * 检查当前log文件数量，并返回新Log文件数量
 */ 
int CheckLogFiles(void)
{
	FILE * fd;
	int index =0;
	unsigned char * tempfilename = malloc(256);
	
	if((fd = fopen(LOG_FILE_LAST, "r"))!= NULL){
		fclose(fd);
		for(index = 0; index < LOG_FILES_MAX; index++)	{
			sprintf(tempfilename, "%s.%d", LOG_FILE_BASE, index);
			if((fd = fopen(tempfilename, "r")) != NULL)	{
					fclose(fd);
					remove(tempfilename);
			}
		}
		rename(LOG_FILE_LAST, LOG_FILE_FIRST);
		return 1;
	}
	else{
		for(index = 0; index <= LOG_FILES_MAX; index ++) {
			sprintf(tempfilename, "%s.%d", LOG_FILE_BASE, index);
			if((fd = fopen(tempfilename, "r")) == NULL) {
				return index;
				}
			else fclose(fd);
			}
		}
}

/*
 * 秒延时
 */ 
void DelaySec(int sec)
{
	int i = 0;
	for(i = 0; i < sec; i++)
	{
		sleep(1);
	}
}

/*
 * 系统重启
 */ 
void SystemReboot(void)
{
	outpw(CLKSEL, (inpw(CLKSEL) | SOFTRESET));	
}

/*
 * 保存最后1MB内存
 */ 
void SaveLast1MB(void)
{
	FILE *fd;
	unsigned int count = 0;
	unsigned char *logname = malloc(256);
	unsigned char temp;
	
	sprintf(logname,"%s.%d", LOG_FILE_BASE, newlogIndex);
	if((fd = fopen(logname, "w+")) == NULL){
		SystemReboot();
	}
	for(count = 0; count < 0x100000; count ++){
		temp = inp(CONSOLE_BASE + count);
		putc( temp,fd);
	}
	fclose(fd);
	DelaySec(10);
	SystemReboot();
}

/*
 * 检查app进程是否工作正常
 */ 
void CheckAppRun(void)
{
	FILE * fd;
	if((fd = fopen(APP_RUN_FILE, "r")) != NULL){
		/* APP Working Failed */
		//printf("app running failed\n");
		fclose(fd);
		remove(APP_RUN_FILE);		
		SaveLast1MB();
	}
	else{
		/* APP Working OK */
		//printf("app running ok \n");
		if((fd = fopen(APP_RUN_FILE, "w+"))==NULL){
			//printf("Create run.in Failed\n");
			return;
		}
		putc('C', fd);
		fclose(fd);
	}

}

/*
 * 检测是否有系统更新行为
 */ 
void CheckSystemUpdate(void)
{
	FILE * fd;
	if((fd = fopen(SYSTEM_UPDATE_FILE, "r")) == NULL){
		return;
	}
	fclose(fd);
	remove(SYSTEM_UPDATE_FILE);
	checkappstatus = CHECK_DISABLE;
	printf("System update!\n");
	system("killall obdapp");

}

/*
 * 检查是否有重启信号
 */ 
void CheckReboot(void)
{
	FILE * fd;
	if((fd = fopen(SYSTEM_REBOOT_FILE, "r")) == NULL){
		return;
	}
	fclose(fd);
	remove(SYSTEM_REBOOT_FILE);
	printf("Reboot@reboot.in\n");
	DelaySec(10);
	SystemReboot();
}

/*
 * 主函数入口
 */ 
int main(int argc, char *argv[])
{
	int CheckCount = 1;

	printf("Guarder Start Runing...\n");
	CheckLogDir();
	newlogIndex = CheckLogFiles();
	DelaySec(1);
	while(1){
		if(CheckCount % TIME_CHECK_RUN == 0 && checkappstatus == CHECK_ENABLE){
			//printf("Check run.in\n");
			CheckAppRun();
		}
		
		if(CheckCount % TIME_CHECK_SYSTEMUPDATE == 0){
			//printf("Check systemupdate.in\n");
			CheckSystemUpdate();
		}

		if(CheckCount % TIME_CHECK_REBOOT == 0){
			//printf("Check reboot.in\n");
			CheckReboot();
		}
		DelaySec(1);
		if(CheckCount++ == 10000) CheckCount = 1;
	}

}
